package com.kalvan.admin.gateway.service;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.kalvan.client.context.RequestContextHolder;
import com.kalvan.client.exception.BizException;
import com.kalvan.commons.constant.AdminContextCacheKey;
import com.kalvan.commons.constant.AdminReturnCode;
import com.kalvan.commons.constant.AuditState;
import com.kalvan.commons.constant.State;
import com.kalvan.commons.db.DataSourceConstants;
import com.kalvan.commons.db.gateway.mapper.GrayRuleMapper;
import com.kalvan.commons.db.gateway.model.GrayRule;
import com.kalvan.db.mybatis.BaseService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Map;

/**
 * 灰度规则配置Service实现类
 *
 * @author kalvan
 */
@Slf4j
@Service("grayRuleService")
public class GrayRuleService extends BaseService<GrayRule> {
    @Resource
    GrayRuleMapper mapper;

    @Override
    public void processParams(Map<String, Object> params) {
        // TODO 查询和下载的条件检查
    }

    @Override
    @Transactional(value = DataSourceConstants.GATEWAY_TRANSACTION_MANAGER, rollbackFor = Exception.class)
    public int add(GrayRule grayRule) {
        // TODO 填充数据,选择字段进行检查，更新人，更新时间，查重
        GrayRule grayRuleQuery = new GrayRule();

        if (mapper.selectCount(grayRuleQuery) > 0) {
            throw new BizException(AdminReturnCode.DATA_REPEAT);
        }
        grayRule.setAuditApplicant(String.valueOf(RequestContextHolder.getContext().get(AdminContextCacheKey.USER_NAME)));
        // TODO 新增审核,业务状态不生效,审核状态为待审核
        grayRule.setState(State.DISABLE.getCode());
        grayRule.setAuditState(AuditState.ADD.getCode());
        return mapper.insertSelective(grayRule);
    }

    @Override
    @Transactional(value = DataSourceConstants.GATEWAY_TRANSACTION_MANAGER, rollbackFor = Exception.class)
    public int edit(GrayRule grayRule) {
        GrayRule grayRuleDb = mapper.selectByUk(grayRule.getId());
        if (grayRuleDb == null) {
            throw new BizException(AdminReturnCode.DATA_NOT_EXISTS);
        }
        // TODO 更新指定字段，更新人
        GrayRule grayRuleNew = new GrayRule();
        grayRuleNew.setId(grayRule.getId());
        grayRuleNew.setAuditApplicant(String.valueOf(RequestContextHolder.getContext().get(AdminContextCacheKey.USER_NAME)));

        // TODO 更新审核,将修改内容保存到json临时字段
        if (grayRuleDb.getAuditState() != AuditState.PASS.getCode()) {
            throw new BizException(AdminReturnCode.DATA_PROCESSING);
        }
        GrayRule grayRuleTemp = new GrayRule();
        grayRuleTemp.setRuleName(grayRule.getRuleName());
        grayRuleTemp.setRule(grayRule.getRule());
        grayRuleTemp.setState(grayRule.getState());

        grayRuleNew.setAuditState(AuditState.UPDATE.getCode());
        grayRuleNew.setAuditTemp(JSONObject.toJSONString(grayRuleTemp));
        return mapper.updateByUkSelective(grayRuleNew);
    }

    @Override
    @Transactional(value = DataSourceConstants.GATEWAY_TRANSACTION_MANAGER, rollbackFor = Exception.class)
    public int deleteBatch(Object[] ids) {
        int resultNum = 0;
        for (Object id : ids) {
            // TODO 删除审核
            GrayRule grayRuleDb = mapper.selectByUk(id);
            if (grayRuleDb.getAuditState() != AuditState.PASS.getCode()) {
                throw new BizException(AdminReturnCode.DATA_PROCESSING);
            }
            GrayRule grayRuleNew = new GrayRule();
            grayRuleNew.setId(grayRuleDb.getId());
            grayRuleNew.setAuditApplicant(String.valueOf(RequestContextHolder.getContext().get(AdminContextCacheKey.USER_NAME)));
            grayRuleNew.setAuditState(AuditState.DELETE.getCode());
            resultNum = resultNum + mapper.updateByUkSelective(grayRuleNew);
        }
        return resultNum;
    }

    @Override
    @Transactional(value = DataSourceConstants.GATEWAY_TRANSACTION_MANAGER, rollbackFor = Exception.class)
    public int auditingBatch(Object[] ids, boolean pass) {
        int resultNum = 0;
        String userCode = String.valueOf(RequestContextHolder.getContext().get(AdminContextCacheKey.USER_NAME));
        for (Object id : ids) {
            GrayRule grayRuleDb = mapper.selectByUk(id);
            if (grayRuleDb.getAuditApplicant().equals(userCode)) {
                throw new BizException(AdminReturnCode.DATA_SELF_AUDIT);
            }
            if (grayRuleDb.getAuditState() == AuditState.PASS.getCode()) {
                continue;
            }
            GrayRule grayRuleNew = new GrayRule();
            if (pass) {
                //修改审核
                if (AuditState.UPDATE.getCode() == grayRuleDb.getAuditState()) {
                    String object = grayRuleDb.getAuditTemp();
                    if (StringUtils.isBlank(object)) {
                        throw new BizException(AdminReturnCode.DATA_NOT_EXISTS);
                    }
                    GrayRule grayRule = JSONObject.parseObject(object, GrayRule.class);
                    BeanUtils.copyProperties(grayRule, grayRuleNew);
                }
                //新增审核通过生效
                if (AuditState.ADD.getCode() == grayRuleDb.getAuditState()) {
                    grayRuleNew.setState(State.ENABLE.getCode());
                }
                //删除审核
                if (AuditState.DELETE.getCode() == grayRuleDb.getAuditState()) {
                    resultNum = resultNum + mapper.deleteByUk(grayRuleDb);
                    continue;
                }
            } else {
                //新增审核不通过删除
                if (AuditState.ADD.getCode() == grayRuleDb.getAuditState()) {
                    resultNum = resultNum + mapper.deleteByUk(grayRuleDb);
                    continue;
                }
            }
            grayRuleNew.setId(grayRuleDb.getId());
            grayRuleNew.setAuditUser(userCode);
            grayRuleNew.setUpdateTime(DateUtil.date());
            //清除审核标记
            grayRuleNew.setAuditState(AuditState.PASS.getCode());
            grayRuleNew.setAuditTemp("{}");
            resultNum = resultNum + mapper.updateByUkSelective(grayRuleNew);
        }
        return resultNum;
    }

}
